{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[<- back to pattern_classification](https://github.com/rasbt/pattern_classification)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%load_ext watermark"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sebastian Raschka 2016-08-31 \n",
      "\n",
      "CPython 3.5.2\n",
      "IPython 5.1.0\n"
     ]
    }
   ],
   "source": [
    "%watermark -a \"Sebastian Raschka\" -d -v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Hierarchical Agglomerative Clustering - Complete Linkage Clustering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### - A quick Python tutorial"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sections"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [Generating some Sample Data](#Generating-some-Sample-Data)\n",
    "- [Pair-wise Distance Matrix, Rows](#Pair-wise-Distance-Matrix,-Rows)\n",
    "- [Apply Clustering - Complete Linkage](#Apply-Clustering---Complete-Linkage)\n",
    "- [Heatmaps](#Heatmaps)\n",
    "    - [Heatmap of the Original Data](#Heatmap-of-the-Original-Data)\n",
    "    - [Heatmap after Row-Clustering](#Heatmap-after-Row-Clustering)\n",
    "    - [Heatmap plus Row-Dendrogram](#[Heatmap-plus-Row-Dendrogram)\n",
    "    - [Adding a Column Dendrogram](#Adding-a-Column-Dendrogram)\n",
    "- [Important Warning About Adding Dendrograms](#Important-Warning-About-Adding-Dendrograms)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**This is a more technical-oriented tutorial that was born out of necessity to plot a heatmap including the dendrograms from a complete linkage clustering. Since I couldn't find any good resource online, I thought that it might be worthwhile sharing it. **"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Therefore, the theoretical aspects are a little bit brief, but nonetheless, here is a short introduction of what it is all about.**\n",
    "\n",
    "Complete linkage is one implementation of *hierarchical agglomerative clustering*. The principle of hierarchical agglomerative clustering is to start with a singleton cluster, and clusters are iteratively merged until one single cluster remains. This results in a \"cluster tree,\" which is also called *dendrogram*. The opposite approach -- starting with one cluster and divide into clusters until only singleton clusters remain -- is called *divisive hierarchical clustering*.\n",
    "\n",
    "The algorithm can be summarized via the following pseudocode\n",
    "\n",
    "<hr>\n",
    "\n",
    "1: Compute a distance or similarity matrix.  \n",
    "2: Each data point is represented as a singleton cluster.  \n",
    "3: **Repeat**  \n",
    "4:  &nbsp;&nbsp;&nbsp;&nbsp;   Merge two closest clusters (e.g., based on distance between most similar or dissimilar members).  \n",
    "5:  &nbsp;&nbsp;&nbsp;&nbsp;   Update the distance (or similarity) matrix.  \n",
    "6: **Until** one single cluster remains.  \n",
    "<hr>\n",
    "\n",
    "Complete linkage compares the most dissimilar members between clusters in each iteration. The two clusters which have the most similar *dissimilar members* are merged into a new cluster.  \n",
    "\\begin{equation}\n",
    "d(C,D) = \\max[dist(C_i, D_j)]\n",
    "\\end{equation}\n",
    "for all $i$  points in cluster $C$ and $j$ points in cluster $D$.\n",
    "\n",
    "\n",
    "In contrast, the *single linkage* algorithm compares the two most similar members instead of the most dissimilar ones.\n",
    "\\begin{equation}\n",
    "d(C,D) = \\min[dist(C_i, D_j)]\n",
    "\\end{equation}\n",
    "for all $i$  points in cluster $C$ and $j$ points in cluster $D$.\n",
    "\n",
    "For more implementations, e.g., `centroid`, `average` etc., please see the [`scipy.cluster.hierarchy.linkage` documentation](http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**(A more detailed article about prototype-based, hierarchical, and density-based clustering is in the planning stage)**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generating some Sample Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we generate some random sample data to work with. Like in a typical application, the rows represent different observations (Samples 1-5), and the columns are the different features (*X, Y, Z*). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "      <th>C</th>\n",
       "      <th>X</th>\n",
       "      <th>Y</th>\n",
       "      <th>Z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>ID_0</th>\n",
       "      <td>6.964692</td>\n",
       "      <td>2.861393</td>\n",
       "      <td>2.268515</td>\n",
       "      <td>5.513148</td>\n",
       "      <td>7.194690</td>\n",
       "      <td>4.231065</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_1</th>\n",
       "      <td>9.807642</td>\n",
       "      <td>6.848297</td>\n",
       "      <td>4.809319</td>\n",
       "      <td>3.921175</td>\n",
       "      <td>3.431780</td>\n",
       "      <td>7.290497</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_2</th>\n",
       "      <td>4.385722</td>\n",
       "      <td>0.596779</td>\n",
       "      <td>3.980443</td>\n",
       "      <td>7.379954</td>\n",
       "      <td>1.824917</td>\n",
       "      <td>1.754518</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_3</th>\n",
       "      <td>5.315514</td>\n",
       "      <td>5.318276</td>\n",
       "      <td>6.344010</td>\n",
       "      <td>8.494318</td>\n",
       "      <td>7.244553</td>\n",
       "      <td>6.110235</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_4</th>\n",
       "      <td>7.224434</td>\n",
       "      <td>3.229589</td>\n",
       "      <td>3.617887</td>\n",
       "      <td>2.282632</td>\n",
       "      <td>2.937140</td>\n",
       "      <td>6.309761</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_5</th>\n",
       "      <td>0.921049</td>\n",
       "      <td>4.337012</td>\n",
       "      <td>4.308628</td>\n",
       "      <td>4.936851</td>\n",
       "      <td>4.258303</td>\n",
       "      <td>3.122612</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_6</th>\n",
       "      <td>4.263513</td>\n",
       "      <td>8.933892</td>\n",
       "      <td>9.441600</td>\n",
       "      <td>5.018367</td>\n",
       "      <td>6.239530</td>\n",
       "      <td>1.156184</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_7</th>\n",
       "      <td>3.172855</td>\n",
       "      <td>4.148262</td>\n",
       "      <td>8.663092</td>\n",
       "      <td>2.504554</td>\n",
       "      <td>4.830343</td>\n",
       "      <td>9.855598</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_8</th>\n",
       "      <td>5.194851</td>\n",
       "      <td>6.128945</td>\n",
       "      <td>1.206287</td>\n",
       "      <td>8.263408</td>\n",
       "      <td>6.030601</td>\n",
       "      <td>5.450680</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_9</th>\n",
       "      <td>3.427638</td>\n",
       "      <td>3.041208</td>\n",
       "      <td>4.170222</td>\n",
       "      <td>6.813008</td>\n",
       "      <td>8.754568</td>\n",
       "      <td>5.104223</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_10</th>\n",
       "      <td>6.693138</td>\n",
       "      <td>5.859366</td>\n",
       "      <td>6.249035</td>\n",
       "      <td>6.746891</td>\n",
       "      <td>8.423424</td>\n",
       "      <td>0.831950</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              A         B         C         X         Y         Z\n",
       "ID_0   6.964692  2.861393  2.268515  5.513148  7.194690  4.231065\n",
       "ID_1   9.807642  6.848297  4.809319  3.921175  3.431780  7.290497\n",
       "ID_2   4.385722  0.596779  3.980443  7.379954  1.824917  1.754518\n",
       "ID_3   5.315514  5.318276  6.344010  8.494318  7.244553  6.110235\n",
       "ID_4   7.224434  3.229589  3.617887  2.282632  2.937140  6.309761\n",
       "ID_5   0.921049  4.337012  4.308628  4.936851  4.258303  3.122612\n",
       "ID_6   4.263513  8.933892  9.441600  5.018367  6.239530  1.156184\n",
       "ID_7   3.172855  4.148262  8.663092  2.504554  4.830343  9.855598\n",
       "ID_8   5.194851  6.128945  1.206287  8.263408  6.030601  5.450680\n",
       "ID_9   3.427638  3.041208  4.170222  6.813008  8.754568  5.104223\n",
       "ID_10  6.693138  5.859366  6.249035  6.746891  8.423424  0.831950"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.ticker as ticker\n",
    "\n",
    "np.random.seed(123)\n",
    "\n",
    "variables = ['A','B','C','X','Y','Z']\n",
    "labels = ['ID_0','ID_1','ID_2','ID_3','ID_4','ID_5','ID_6',\n",
    "          'ID_7','ID_8','ID_9','ID_10']\n",
    "\n",
    "X = np.random.random_sample([len(labels),len(variables)])*10\n",
    "df = pd.DataFrame(X, columns=variables, index=labels)\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Pair-wise Distance Matrix, Rows"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we calculate the pair-wise distances for every row (i.e, between every sample across the different variables). We will use the default euclidean distance measure. The other available distance measures are listed in the [`scipy.spatial.distance.pdist` documentation](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.distance.pdist.html#scipy.spatial.distance.pdist) with a nice and short explanatory paragraph. In addition, we use the [`squareform`](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.distance.squareform.html#scipy.spatial.distance.squareform) function to return a symmetrical matrix of the pair-wise distances."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID_0</th>\n",
       "      <th>ID_1</th>\n",
       "      <th>ID_2</th>\n",
       "      <th>ID_3</th>\n",
       "      <th>ID_4</th>\n",
       "      <th>ID_5</th>\n",
       "      <th>ID_6</th>\n",
       "      <th>ID_7</th>\n",
       "      <th>ID_8</th>\n",
       "      <th>ID_9</th>\n",
       "      <th>ID_10</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>ID_0</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>7.515813</td>\n",
       "      <td>7.291294</td>\n",
       "      <td>6.147102</td>\n",
       "      <td>5.908280</td>\n",
       "      <td>7.283425</td>\n",
       "      <td>10.307123</td>\n",
       "      <td>10.158830</td>\n",
       "      <td>5.034288</td>\n",
       "      <td>4.587465</td>\n",
       "      <td>6.284267</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_1</th>\n",
       "      <td>7.515813</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>10.693828</td>\n",
       "      <td>7.856166</td>\n",
       "      <td>5.007880</td>\n",
       "      <td>10.228137</td>\n",
       "      <td>10.161800</td>\n",
       "      <td>8.758121</td>\n",
       "      <td>7.985670</td>\n",
       "      <td>9.852989</td>\n",
       "      <td>9.346920</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_2</th>\n",
       "      <td>7.291294</td>\n",
       "      <td>10.693828</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>8.850425</td>\n",
       "      <td>7.943009</td>\n",
       "      <td>6.313700</td>\n",
       "      <td>11.170073</td>\n",
       "      <td>11.594865</td>\n",
       "      <td>8.431215</td>\n",
       "      <td>8.154213</td>\n",
       "      <td>9.108111</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_3</th>\n",
       "      <td>6.147102</td>\n",
       "      <td>7.856166</td>\n",
       "      <td>8.850425</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>8.521560</td>\n",
       "      <td>7.410542</td>\n",
       "      <td>7.836414</td>\n",
       "      <td>8.189719</td>\n",
       "      <td>5.387945</td>\n",
       "      <td>4.426452</td>\n",
       "      <td>5.873941</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_4</th>\n",
       "      <td>5.908280</td>\n",
       "      <td>5.007880</td>\n",
       "      <td>7.943009</td>\n",
       "      <td>8.521560</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>7.770742</td>\n",
       "      <td>10.962260</td>\n",
       "      <td>7.675921</td>\n",
       "      <td>8.026113</td>\n",
       "      <td>8.400971</td>\n",
       "      <td>9.703415</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_5</th>\n",
       "      <td>7.283425</td>\n",
       "      <td>10.228137</td>\n",
       "      <td>6.313700</td>\n",
       "      <td>7.410542</td>\n",
       "      <td>7.770742</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>8.151657</td>\n",
       "      <td>8.697356</td>\n",
       "      <td>7.122349</td>\n",
       "      <td>5.970293</td>\n",
       "      <td>8.079069</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_6</th>\n",
       "      <td>10.307123</td>\n",
       "      <td>10.161800</td>\n",
       "      <td>11.170073</td>\n",
       "      <td>7.836414</td>\n",
       "      <td>10.962260</td>\n",
       "      <td>8.151657</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>10.425101</td>\n",
       "      <td>10.274831</td>\n",
       "      <td>9.399096</td>\n",
       "      <td>5.780188</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_7</th>\n",
       "      <td>10.158830</td>\n",
       "      <td>8.758121</td>\n",
       "      <td>11.594865</td>\n",
       "      <td>8.189719</td>\n",
       "      <td>7.675921</td>\n",
       "      <td>8.697356</td>\n",
       "      <td>10.425101</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>10.845452</td>\n",
       "      <td>8.832567</td>\n",
       "      <td>11.553433</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_8</th>\n",
       "      <td>5.034288</td>\n",
       "      <td>7.985670</td>\n",
       "      <td>8.431215</td>\n",
       "      <td>5.387945</td>\n",
       "      <td>8.026113</td>\n",
       "      <td>7.122349</td>\n",
       "      <td>10.274831</td>\n",
       "      <td>10.845452</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>5.575461</td>\n",
       "      <td>7.556781</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_9</th>\n",
       "      <td>4.587465</td>\n",
       "      <td>9.852989</td>\n",
       "      <td>8.154213</td>\n",
       "      <td>4.426452</td>\n",
       "      <td>8.400971</td>\n",
       "      <td>5.970293</td>\n",
       "      <td>9.399096</td>\n",
       "      <td>8.832567</td>\n",
       "      <td>5.575461</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>6.425987</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>ID_10</th>\n",
       "      <td>6.284267</td>\n",
       "      <td>9.346920</td>\n",
       "      <td>9.108111</td>\n",
       "      <td>5.873941</td>\n",
       "      <td>9.703415</td>\n",
       "      <td>8.079069</td>\n",
       "      <td>5.780188</td>\n",
       "      <td>11.553433</td>\n",
       "      <td>7.556781</td>\n",
       "      <td>6.425987</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            ID_0       ID_1       ID_2      ID_3       ID_4       ID_5  \\\n",
       "ID_0    0.000000   7.515813   7.291294  6.147102   5.908280   7.283425   \n",
       "ID_1    7.515813   0.000000  10.693828  7.856166   5.007880  10.228137   \n",
       "ID_2    7.291294  10.693828   0.000000  8.850425   7.943009   6.313700   \n",
       "ID_3    6.147102   7.856166   8.850425  0.000000   8.521560   7.410542   \n",
       "ID_4    5.908280   5.007880   7.943009  8.521560   0.000000   7.770742   \n",
       "ID_5    7.283425  10.228137   6.313700  7.410542   7.770742   0.000000   \n",
       "ID_6   10.307123  10.161800  11.170073  7.836414  10.962260   8.151657   \n",
       "ID_7   10.158830   8.758121  11.594865  8.189719   7.675921   8.697356   \n",
       "ID_8    5.034288   7.985670   8.431215  5.387945   8.026113   7.122349   \n",
       "ID_9    4.587465   9.852989   8.154213  4.426452   8.400971   5.970293   \n",
       "ID_10   6.284267   9.346920   9.108111  5.873941   9.703415   8.079069   \n",
       "\n",
       "            ID_6       ID_7       ID_8      ID_9      ID_10  \n",
       "ID_0   10.307123  10.158830   5.034288  4.587465   6.284267  \n",
       "ID_1   10.161800   8.758121   7.985670  9.852989   9.346920  \n",
       "ID_2   11.170073  11.594865   8.431215  8.154213   9.108111  \n",
       "ID_3    7.836414   8.189719   5.387945  4.426452   5.873941  \n",
       "ID_4   10.962260   7.675921   8.026113  8.400971   9.703415  \n",
       "ID_5    8.151657   8.697356   7.122349  5.970293   8.079069  \n",
       "ID_6    0.000000  10.425101  10.274831  9.399096   5.780188  \n",
       "ID_7   10.425101   0.000000  10.845452  8.832567  11.553433  \n",
       "ID_8   10.274831  10.845452   0.000000  5.575461   7.556781  \n",
       "ID_9    9.399096   8.832567   5.575461  0.000000   6.425987  \n",
       "ID_10   5.780188  11.553433   7.556781  6.425987   0.000000  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from scipy.spatial.distance import pdist,squareform\n",
    "\n",
    "row_dist = pd.DataFrame(squareform(pdist(df, metric='euclidean')), columns=labels, index=labels)\n",
    "row_dist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Apply Clustering - Complete Linkage"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When we apply the complete linkage agglomeration to our clusters, the `linkage` function returns a so-called `linkage matrix`. \n",
    "This `linkage matrix` consists of several rows where each row consists of 1 merge. The first and second column denote the most dissimilar members in each cluster, and the third row reports the distance between those members. The last column returns the count of members in the clusters."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, before we call the `linkage` function, let us take a careful look at its [documentation](http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage). \n",
    "\n",
    "> Parameters:\t\n",
    "**y** : ndarray  \n",
    "    A condensed or redundant distance matrix. A condensed distance matrix is a flat array containing the upper triangular of the distance matrix. This is the form that pdist returns. Alternatively, a collection of m observation vectors in n dimensions may be passed as an m by n array.  \n",
    "    \n",
    "> **method** : str, optional  \n",
    "The linkage algorithm to use. See the Linkage Methods section below for full descriptions.\n",
    "\n",
    "> **metric** : str, optional  \n",
    "The distance metric to use. See the distance.pdist function for a list of valid distance metrics.\n",
    "\n",
    "> Returns:\t\n",
    "**Z** : ndarray  \n",
    "The hierarchical clustering encoded as a linkage matrix.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Thus, we can either pass a condensed distance matrix (upper triangular) from the `pdist` function, or we can pass the \"original\" data array and define the `'euclidean'` metric as  function argument in `linkage`. However, we shouldn't pass the `squareform` distance metrics, which would yield incorrect distance values although the overall clustering could be the same. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### a) Squareform distance matrix (wrong)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row label 1</th>\n",
       "      <th>row label 2</th>\n",
       "      <th>distance</th>\n",
       "      <th>no. of items in clust.</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>cluster 1</th>\n",
       "      <td>3.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>7.167666</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 2</th>\n",
       "      <td>0.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>7.769408</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 3</th>\n",
       "      <td>1.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>8.416614</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 4</th>\n",
       "      <td>11.0</td>\n",
       "      <td>12.0</td>\n",
       "      <td>9.760483</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 5</th>\n",
       "      <td>2.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>10.348596</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 6</th>\n",
       "      <td>6.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>10.529093</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 7</th>\n",
       "      <td>7.0</td>\n",
       "      <td>13.0</td>\n",
       "      <td>13.599170</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 8</th>\n",
       "      <td>14.0</td>\n",
       "      <td>15.0</td>\n",
       "      <td>14.962794</td>\n",
       "      <td>6.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 9</th>\n",
       "      <td>16.0</td>\n",
       "      <td>18.0</td>\n",
       "      <td>17.737253</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 10</th>\n",
       "      <td>17.0</td>\n",
       "      <td>19.0</td>\n",
       "      <td>18.345150</td>\n",
       "      <td>11.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            row label 1  row label 2   distance  no. of items in clust.\n",
       "cluster 1           3.0          9.0   7.167666                     2.0\n",
       "cluster 2           0.0          8.0   7.769408                     2.0\n",
       "cluster 3           1.0          4.0   8.416614                     2.0\n",
       "cluster 4          11.0         12.0   9.760483                     4.0\n",
       "cluster 5           2.0          5.0  10.348596                     2.0\n",
       "cluster 6           6.0         10.0  10.529093                     2.0\n",
       "cluster 7           7.0         13.0  13.599170                     3.0\n",
       "cluster 8          14.0         15.0  14.962794                     6.0\n",
       "cluster 9          16.0         18.0  17.737253                     8.0\n",
       "cluster 10         17.0         19.0  18.345150                    11.0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from scipy.cluster.hierarchy import linkage\n",
    "\n",
    "row_clusters = linkage(row_dist, method='complete', metric='euclidean')\n",
    "pd.DataFrame(row_clusters, \n",
    "             columns=['row label 1', 'row label 2', 'distance', 'no. of items in clust.'],\n",
    "             index=['cluster %d' %(i+1) for i in range(row_clusters.shape[0])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### b) Condensed distance matrix (correct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row label 1</th>\n",
       "      <th>row label 2</th>\n",
       "      <th>distance</th>\n",
       "      <th>no. of items in clust.</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>cluster 1</th>\n",
       "      <td>3.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>4.426452</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>5.007880</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>5.034288</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 4</th>\n",
       "      <td>6.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5.780188</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 5</th>\n",
       "      <td>11.0</td>\n",
       "      <td>13.0</td>\n",
       "      <td>6.147102</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 6</th>\n",
       "      <td>2.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>6.313700</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 7</th>\n",
       "      <td>7.0</td>\n",
       "      <td>12.0</td>\n",
       "      <td>8.758121</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 8</th>\n",
       "      <td>15.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>8.850425</td>\n",
       "      <td>6.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 9</th>\n",
       "      <td>14.0</td>\n",
       "      <td>18.0</td>\n",
       "      <td>11.170073</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 10</th>\n",
       "      <td>17.0</td>\n",
       "      <td>19.0</td>\n",
       "      <td>11.594865</td>\n",
       "      <td>11.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            row label 1  row label 2   distance  no. of items in clust.\n",
       "cluster 1           3.0          9.0   4.426452                     2.0\n",
       "cluster 2           1.0          4.0   5.007880                     2.0\n",
       "cluster 3           0.0          8.0   5.034288                     2.0\n",
       "cluster 4           6.0         10.0   5.780188                     2.0\n",
       "cluster 5          11.0         13.0   6.147102                     4.0\n",
       "cluster 6           2.0          5.0   6.313700                     2.0\n",
       "cluster 7           7.0         12.0   8.758121                     3.0\n",
       "cluster 8          15.0         16.0   8.850425                     6.0\n",
       "cluster 9          14.0         18.0  11.170073                     8.0\n",
       "cluster 10         17.0         19.0  11.594865                    11.0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "row_clusters = linkage(pdist(df, metric='euclidean'), method='complete')\n",
    "pd.DataFrame(row_clusters, \n",
    "             columns=['row label 1', 'row label 2', 'distance', 'no. of items in clust.'],\n",
    "             index=['cluster %d' %(i+1) for i in range(row_clusters.shape[0])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### c) Input sample matrix (correct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row label 1</th>\n",
       "      <th>row label 2</th>\n",
       "      <th>distance</th>\n",
       "      <th>no. of items in clust.</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>cluster 1</th>\n",
       "      <td>3.0</td>\n",
       "      <td>9.0</td>\n",
       "      <td>4.426452</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>5.007880</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>5.034288</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 4</th>\n",
       "      <td>6.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5.780188</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 5</th>\n",
       "      <td>11.0</td>\n",
       "      <td>13.0</td>\n",
       "      <td>6.147102</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 6</th>\n",
       "      <td>2.0</td>\n",
       "      <td>5.0</td>\n",
       "      <td>6.313700</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 7</th>\n",
       "      <td>7.0</td>\n",
       "      <td>12.0</td>\n",
       "      <td>8.758121</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 8</th>\n",
       "      <td>15.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>8.850425</td>\n",
       "      <td>6.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 9</th>\n",
       "      <td>14.0</td>\n",
       "      <td>18.0</td>\n",
       "      <td>11.170073</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cluster 10</th>\n",
       "      <td>17.0</td>\n",
       "      <td>19.0</td>\n",
       "      <td>11.594865</td>\n",
       "      <td>11.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            row label 1  row label 2   distance  no. of items in clust.\n",
       "cluster 1           3.0          9.0   4.426452                     2.0\n",
       "cluster 2           1.0          4.0   5.007880                     2.0\n",
       "cluster 3           0.0          8.0   5.034288                     2.0\n",
       "cluster 4           6.0         10.0   5.780188                     2.0\n",
       "cluster 5          11.0         13.0   6.147102                     4.0\n",
       "cluster 6           2.0          5.0   6.313700                     2.0\n",
       "cluster 7           7.0         12.0   8.758121                     3.0\n",
       "cluster 8          15.0         16.0   8.850425                     6.0\n",
       "cluster 9          14.0         18.0  11.170073                     8.0\n",
       "cluster 10         17.0         19.0  11.594865                    11.0"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "row_clusters = linkage(df.values, method='complete', metric='euclidean')\n",
    "pd.DataFrame(row_clusters, \n",
    "             columns=['row label 1', 'row label 2', 'distance', 'no. of items in clust.'],\n",
    "             index=['cluster %d' %(i+1) for i in range(row_clusters.shape[0])])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW0AAAEACAYAAAB4ayemAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAETZJREFUeJzt3X2sZHV9x/H3Fxa0VB72ErEpCOsjKoIEo6AijNAESm2R\nWFu0CkijaUUltmkRaMrdpk2rCTWgxmpBKq1UC7Ug9gFCYIhLqwLKgvIgKj7xsBT2wmIBYdlv/ziz\nm+t92Jk558zM/d37fiULM5PzO9/fnDv3c3/nN+chMhNJUhl2mHQHJEmDM7QlqSCGtiQVxNCWpIIY\n2pJUEENbkgrSN7Qj4sKI2BARt8567aMRcUdE3BIR/xoRu422m5IkGGykfRFwzJzXrgYOyMyDgbuB\nM9vumCRpvlX9FsjMdRGx35zXrpn19GvAWxdrHxGevSNJNWRmzH2tb2gP4FTgC30Kt1BGklaOiHl5\nDTT8IjIizgaezsxLmqxHkjSY2iPtiDgFOA44qt+y09PT2x53Oh06nU7dspK0LHW7Xbrdbt/lYpCp\ni4hYA1yZmQf2nh8LnAsckZkP92mbTo9I0nAiYsE57b6hHRGXAB1gT2ADcA5wFrAzsDWwv5aZ71uk\nvaEtSUOqHdotFDa0JWlIi4W2Z0RKUkEMbUkqiKEtSQVp4+SaIk1NwczMpHuh5Wr1ati4cdK90HK0\nYr+IjIAl2C0tE36+1JRfRErSMmBoS1JBDG1JKoihLUkFMbQlqSCGtiQVZMUep612edz7fItcw37F\n8tj1dnictlrh9lQ/fkaG43HakrQMGNqSVBBDW5IKYmhLUkEMbUkqiKEtSQUxtCWpIIa2JBXE0Jak\nghjaklQQQ1uSCmJoS1JBDG1JKoihLUkFMbQlqSB9QzsiLoyIDRFx66zXVkfE1RFxV0RcFRG7j7ab\nkiQYbKR9EXDMnNc+DFyTmfsD1wJntt0xSdJ8fUM7M9cBc28kdTzwud7jzwFvablfkqQF1J3T3isz\nNwBk5gPAXu11SZK0mLZu7LvdO79NT09ve9zpdOh0Oi2VlaTlodvt0u12+y430I19I2I/4MrMPKj3\n/A6gk5kbIuJXgOsy8+WLtPXGviuA21P9+BkZTtMb+0bv31ZfBk7pPT4ZuKJR7yRJA+k70o6IS4AO\nsCewATgHuBy4FHg+8CPgdzLzkUXaO9JeAdye6sfPyHAWG2kPND3SsLChvQK4PdWPn5HhNJ0ekSQt\nAYa2JBXE0JakghjaklQQQ1uSCmJoS1JBDG1JKoihLUkFMbQlqSCGtiQVxNCWpIIY2pJUEENbkgpi\naEtSQQxtSSqIoS1JBTG0Jakgbd2NXdKYTE3BzMyke1FPzLsPy9K2ejVs3DjpXvyiJX27sVI/nEvx\nBz1q3kpqfNzW4zPJbV3kPSJL/XCW2u8mVuJ7nhS39fgsxdB2TluSCmJoS1JBDG1JKoihLUkFMbQl\nqSCGtiQVxNCWpIIY2pJUkEahHREfiohvR8StEfH5iNi5rY5JkuarHdoR8avAB4BDMvMgquuYnNhW\nxyRJ8zW9YNSOwC9HxBZgF+C+5l2SJC2m9kg7M+8DzgV+DNwLPJKZ17TVMUnSfLVH2hGxB3A8sB/w\nKHBZRLwjMy+Zu+z09PS2x51Oh06nU7esJC1L3W6Xbrfbd7naV/mLiN8GjsnM9/Sevws4NDPfP2c5\nr/K3AqzE9zwpbuvxWW5X+fsxcFhEPDsiAjgauKPB+iRJfTSZ0/4GcBnwLWA9EMBnWuqXJGkB3gRh\nBErtdxMr8T1Pitt6fJbb9IgkacwMbUkqiKEtSQUxtCWpIIa2JBXE0JakghjaklQQQ1uSCmJoS1JB\nDG1JKoihLUkFMbQlqSCGtiQVxNCWpIIY2pJUEENbkgpiaEtSQQxtSSqIoS1JBTG0JakghrYkFcTQ\nlqSCGNqSVBBDW5IKYmhLUkEMbUkqyKpJd0CSRmnd1Do2z2yu1fZk1tCNH9auvWr1Kg7feHjt9guu\ns0njiNgduAB4JbAFODUzv95GxySpDZtnNtPJTq22Vas1tWt3o1u77WKajrTPA/4jM98WEauAXVro\nkyRpEbVDOyJ2A96YmacAZOZmYFNL/ZKWvKl165jZXG+3u5GT1xDdH4697OpVq9h4eLu7+hpek5H2\nC4CHIuIi4FXATcDpmflEKz2TlriZzZvJTmf8hTvQZJe9ruh2x15T8zU5emQVcAjwycw8BHgc+HAr\nvZIkLajJSPunwE8y86be88uAMxZacHp6etvjTqdDZxKjE0lawrrdLt0B9mZqh3ZmboiIn0TESzPz\nu8DRwO0LLTs7tCVJ880d0K5du3bB5ZoePfJB4PMRsRPwA+DdDdcnSdqORqGdmeuB17TUF0lSH57G\nrsrUFETU/ncO0/XbT01N+t1LxfA0dlVmZiCzdvPpWf8dWkTtutJK40hbkgpiaEtSQQxtSSqIoS1J\nBTG0JakghrYkFcTQlqSCGNqSVBBDW5IKYmhLUkEMbUkqiKEtSQXxglGLmPrIFDNPztRrfOQ5xCIX\nMO9n9bNXs/GMjfXqSn00vRlxk/tEemPgdhjai5h5coY8p+ZV786Bule8i7Ve8U6jM7GbEeONgdvi\n9IgkFcTQlqSCGNqSVBBDW5IKYmhLUkEMbUkqiKEtSQUxtCWpIIa2JBXEMyK1YjU9pRvqn+XnKd2q\ny9DWiuUp3SqR0yOSVJDGoR0RO0TENyPiy210SJK0uDZG2qcDt7ewHklSH41COyL2AY4DLminO5Kk\n7Wk60v4Y8CdAzQtPS5KGUfvokYj4DWBDZt4SER1g0av3T09Pb3vc6XToTOgbe0laqrrdLt0Bjipq\ncsjfG4DfiojjgF8Cdo2IizPzpLkLzg5tSdJ8cwe0axe5ZWHt6ZHMPCsz983MFwInAtcuFNiSpPZ4\nnLYkFaSVMyIz83rg+jbWJUlanCNtSSqIoS1JBTG0JakghrYkFcTQlqSCGNqSVBBDW5IKYmhLUkEM\nbUkqiKEtSQUxtCWpIIa2JBXE0JakghjaklQQQ1uSCmJoS1JBDG1JKoihLUkFMbQlqSCGtiQVxNCW\npIIY2pJUEENbkgpiaEtSQQxtSSqIoS1JBTG0JakghrYkFaR2aEfEPhFxbUR8JyJui4gPttkxSdJ8\nqxq03Qz8UWbeEhHPAW6OiKsz886W+iZJmqP2SDszH8jMW3qPfwbcAezdVsckSfO1MqcdEWuAg4Gv\nt7E+SdLCmkyPANCbGrkMOL034p5nenp62+NOp0On02laVpKWlW63S7fb7btco9COiFVUgf2PmXnF\nYsvNDm1J0nxzB7Rr165dcLmm0yOfBW7PzPMarkeSNIAmh/y9Afg94KiI+FZEfDMijm2va5KkuWpP\nj2TmDcCOLfZFktSHZ0RKUkEMbUkqiKEtSQUxtCWpIIa2JBXE0JakghjaklQQQ1uSCmJoS1JBDG1J\nKoihLUkFMbQlqSCGtiQVxNCWpIIY2pJUEENbkgpiaEtSQQxtSSqIoS1JBTG0JakghrYkFcTQlqSC\nGNqSVBBDW5IKYmhLUkEMbUkqiKEtSQVpFNoRcWxE3BkR342IM9rqlCRpYbVDOyJ2AD4BHAMcALw9\nIl7WVsckSfM1GWm/Frg7M3+UmU8DXwCOb6dbkqSFNAntvYGfzHr+095rkqQR8YtISSrIqgZt7wX2\nnfV8n95r80RE7SINmjYW05MpPqm6k93YE9rWE6k62dor8T0vpzcdmVmvYcSOwF3A0cD9wDeAt2fm\nHe11T5I0W+2RdmY+ExHvB66mmma50MCWpNGqPdKWJI2fX0RKUkEMbUkqyFhDOyLuiYijIuLkiNgc\nEZt6/74fEZ+NiJcMsI7DI+KxWW0fi4gtEXHCqGv31vPp3qn7z0TESeN4z3PWd1Lv/Z46jroRsUNE\n/GVE3Ntrf3NE7DaiWtvdthHxoYi4PyIeiYgLImKntvsREXtGxLqIeCgiZiLihoh4/QDt2toGvxkR\nt/XarouIl4+p7sERcVNE/F9E3BgRrxrjez6q97l6NCK+FxHvGXXdiHhJRFweEQ/2ftb/GREvHdP7\n3RJVbm3Nsc8M0m6rSY60/zszdwN2B34NeAK4OSJesb1GmbkuM3fNzN167d8MPAb816hr99wC/CFw\n8xD12qhLROwBnAl8e4x1/wI4DDi0t453AU+OqNai2zYijgH+FHgTsB/wImDtCPrxM+D3gb0yczXw\nUeDKqC7bMKhatSPixcA/Ae8F9gC+Anx5iNp16+4EXA5c3Kt7MXBFRAxzoELd2quALwGfyszdgROB\nv42IA0dZl+p9XgG8FHgecGPv+aCafM4TOGhWjr13iLqTnx7Jyj2ZeRpwPTA95CpOAS7LzCfGUTsz\nP5WZ1wE/H7Zek7o9fw2cBzw8jrq9PxKnA+/JzJ/21nF7Zj7Vdq1em+1t25OojlC6MzMfpfpj8u62\n+5GZP8/MuzJzS0QEsIXqF3yqX62mtamu4/PVzPyfzNwCfITqLOMjR1y3A+yYmedn5tOZ+XGqo4uP\nGqZuzdpTwK5Uf6zIzJuAO4CBBjJ162bmjZl5UWY+kpnPAB8D9o+I1aOs2xM0yN6Jh/YcXwLeOOjC\nEbEL8FbgH8Zdu0UD1Y2I1wKvzsy/G2PdA4Gngbf1piXujIj3jahWPwcA62c9Xw/sNeQv2cD9iIj1\nVHsUlwN/n5kPDVGnUe1ZdqD6BX/liOseANw657X1vdeb6Fs7Mx8E/hk4NaqpuNdRnbS3bpR1F3Ak\ncH9mzoyp7vURcV9EXBYR+w1TZKmF9n0MN6J5K/C/mfnVCdRuS9+6vd3jTwKnjbMu1VmuewAvoZqS\neBswHRFHj6BWP88BHp31fBNVoO06in5k5qt6634HcMMQNZrUvgY4MiKO6E1ZnAXsBOwy4rpzty1U\n23eYbVu3NlQXm/tzqj2s64GzM3PBs6tbrgtAROxDdcXSDzWoOUzdI4A1wMuoTkz8yjDTb0sttPcG\nNg6x/ElU82+TqN2WQeqeBqzPzBvHXPcJqvm3tZn5VGbeRvULdtwIavXzM2D2F6C79/r22Kj60XvP\nXwTOHGKOtXbtzLwLOJnqD/TWALid6mJsI6vL/G0L1fYdZtvWqh0R+wNfBN6ZmTtRje7PiIhfH2Xd\nWfWfC1wFfCIz/6VBzYHrZvW93ObM3EQ1/bgG2O4XzrMttdA+ARho1Nz769ihvdAeuHbLBql7FHBC\nb4rifuD1wLkRcf6I687dZYYqKEdRq5/vALOPaDgY2DDk7mzdfuwEvLBGu6FrZ+aXMvPAzHwu1fzo\nC6i+JBtl3e8AB8157aDe600MUvuVwJ2ZeQ1AZt4N/DvQJLQH2ta972yuAi7PzL9pUG+ounO7Mef/\nfTW5YFRTAdt2/fcF/phqXumwAdufBNyQmfeMs3Zvt3XH3jp2johnAU9lDnRqad26JwPPnvX834BL\ngQsHqFm7bmb+ICK+CpwdEadTHbFxIvC7bdfqtdnetr0YuCgiLgEeAP4MuKjtfkTEoVS/F9/o9eV0\nYC/g6/3637R2r80hVEfR7Em1y355Zn53xHW7wDMR8QHg08AfUH0Be+2AdZvU/hbw4oh4U2ZeFxEv\nojoibNAQrftz3pXqEhzrMvPsAWu1UfcVVIOA26imvf6Kak9q4EuAjHukPTvYDouITVRzaddRzau9\nJjNvH3Bd72S4LyDbqn018DjwOqoP+ONs/8uHxnUzc1NmPrj1H9Xc36bM3N7ua1vv9+1Uu28PA1dS\nzTd2R1Rr0W2bmVdRHX53HXAP8H3mf1PfRj+eRTU98RDVL9OxwHGZ+UCfdm1tg/OAR6h+iR+mOvxv\npHWzuonJW6gGBzNUA6LjM3PzGGr/gOoQy/MjYmvbSzNzewOSNrb1CcCrgXfPOWZ6nxHXfR7VdNCj\nwPeA5wNv7h3BMhCvPSJJBVlqc9qSpO1YkqEdEe+IXzxVfevp6rct19oroe4kf65LpR8r4ee8VGov\n17pOj0hSQZbkSFuStDBDW5IKYmhLUkEMbUkqiKEtSQX5f9T2d5fq0f4jAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x104a4da58>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "from scipy.cluster.hierarchy import dendrogram\n",
    "\n",
    "row_dendr = dendrogram(row_clusters, labels=labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Heatmaps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This section is about the visualization of our hierarchical clustering. Here, we will plot simple heatmaps for each scenario: The original data, the data after row clustering, and eventually the data after we applied row and column clustering."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Heatmap of the Original Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x114353128>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "\n",
    "ax = fig.add_subplot(111)\n",
    "\n",
    "cax = ax.matshow(df, interpolation='nearest', cmap='hot_r')\n",
    "fig.colorbar(cax)\n",
    "\n",
    "tick_spacing = 1\n",
    "ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "ax.yaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "\n",
    "ax.set_xticklabels([''] + list(df.columns))\n",
    "ax.set_yticklabels([''] + list(df.index))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Heatmap after Row-Clustering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `dendrogram` function returns a dictionary with various items which are explained in detail in the scipy documenation [here](http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.dendrogram.html). The dendrogram leave order can then be accessed via the `'leaves'` key, e.g.,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[7, 1, 4, 6, 10, 3, 9, 0, 8, 2, 5]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "row_dendr['leaves']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Thus, in order to sort the DataFrame according to the clustering, we can simply use the `'leaves'` as indices like so:  \n",
    "\n",
    "    df.ix[row_dendr['leaves']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x114597b38>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# reorder rows with respect to the clustering\n",
    "row_dendr = dendrogram(row_clusters, labels=labels, no_plot=True)\n",
    "df_rowclust = df.ix[row_dendr['leaves']]\n",
    "\n",
    "# plot\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "\n",
    "cax = ax.matshow(df_rowclust, \n",
    "                 interpolation='nearest', \n",
    "                 cmap='hot_r')\n",
    "fig.colorbar(cax)\n",
    "\n",
    "tick_spacing = 1\n",
    "ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "ax.yaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "\n",
    "ax.set_xticklabels([''] + list(df_rowclust.columns))\n",
    "ax.set_yticklabels([''] + list(df_rowclust.index))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Heatmap plus Row-Dendrogram"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we can rotate the dendrogram via the by setting the `orientation` parameter to `'right'`, but note that\n",
    "we now have to sort the clustered data in reverse order to match the row labels in the heatmap via\n",
    "\n",
    "    df.ix[row_dendr['leaves'][::-1]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x114c1ae80>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy.cluster import hierarchy\n",
    "# makes dendrogram black (1)\n",
    "hierarchy.set_link_color_palette(['black'])\n",
    "\n",
    "# plot row dendrogram\n",
    "fig = plt.figure(figsize=(8,8))\n",
    "axd = fig.add_axes([0.09,0.1,0.2,0.6])\n",
    "row_dendr = dendrogram(row_clusters, orientation='left', \n",
    "                   color_threshold=np.inf, ) # makes dendrogram black (2))\n",
    "\n",
    "# reorder data with respect to clustering\n",
    "df_rowclust = df.ix[row_dendr['leaves'][::-1]]\n",
    "\n",
    "axd.set_xticks([])\n",
    "axd.set_yticks([])\n",
    "\n",
    "\n",
    "# remove axes spines from dendrogram\n",
    "for i in axd.spines.values():\n",
    "        i.set_visible(False)\n",
    "\n",
    "# reorder rows with respect to the clustering\n",
    "df_rowclust = df.ix[row_dendr['leaves'][::-1]]\n",
    "        \n",
    "# plot heatmap\n",
    "axm = fig.add_axes([0.20, 0.1, 0.6, 0.6]) # x-pos, y-pos, width, height\n",
    "cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r')\n",
    "fig.colorbar(cax)\n",
    "axm.set_xticklabels([''] + list(df_rowclust.columns))\n",
    "axm.set_yticklabels([''] + list(df_rowclust.index))\n",
    "\n",
    "tick_spacing = 1\n",
    "axm.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "axm.yaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding a Column Dendrogram"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Also, we can add a an additional dendrogram for the column clustering at the top. Here, we first sort the indexes after clustering the rows\n",
    "\n",
    "    df_rowclust = df.ix[row_dendr['leaves'][::-1]]\n",
    "    \n",
    "And then we can use the indices from the column clustering to reorder the columns:\n",
    "\n",
    "    df_rowclust.columns = [df_rowclust.columns[col_dendr['leaves']]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\ngg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1146b07f0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Compute pairwise distances for columns\n",
    "col_dists = pdist(df.T, metric='euclidean')\n",
    "col_clusters = linkage(col_dists, method='complete')\n",
    "\n",
    "# plot column dendrogram\n",
    "fig = plt.figure(figsize=(8,8))\n",
    "\n",
    "axd2 = fig.add_axes([0.38,0.74,0.36,0.10]) \n",
    "col_dendr = dendrogram(col_clusters, orientation='top',\n",
    "                       color_threshold=np.inf) # makes dendrogram black)\n",
    "axd2.set_xticks([])\n",
    "axd2.set_yticks([])\n",
    "\n",
    "# plot row dendrogram\n",
    "axd1 = fig.add_axes([0.09,0.1,0.2,0.6])\n",
    "row_dendr = dendrogram(row_clusters, orientation='left',  \n",
    "                       count_sort='ascending',\n",
    "                       color_threshold=np.inf) # makes dendrogram black\n",
    "axd1.set_xticks([])\n",
    "axd1.set_yticks([])\n",
    "\n",
    "# remove axes spines from dendrogram\n",
    "for i,j in zip(axd1.spines.values(), axd2.spines.values()):\n",
    "        i.set_visible(False)\n",
    "        j.set_visible(False)\n",
    "        \n",
    "\n",
    "# reorder columns and rows with respect to the clustering\n",
    "df_rowclust = df.ix[row_dendr['leaves'][::-1]]\n",
    "df_rowclust.columns = [df_rowclust.columns[col_dendr['leaves']]]\n",
    "\n",
    "# plot heatmap\n",
    "axm = fig.add_axes([0.20,0.1,0.6,0.6])\n",
    "cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r')\n",
    "fig.colorbar(cax)\n",
    "axm.set_xticklabels([''] + list(df_rowclust.columns))\n",
    "axm.set_yticklabels([''] + list(df_rowclust.index))\n",
    "\n",
    "tick_spacing = 1\n",
    "axm.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "axm.yaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<br>\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Important Warning About Adding Dendrograms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[[back to top](#Sections)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is very important that you always check that the labels on the heatmap and the dendrogram match when you create the first plot! For example, we can provide the `labels` to the `labels` parameter of the dendrogram and **DON'T set `axd.set_yticks([])`** to show the labels on the dendrogram to compare them to the heatmap labels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nWdf+PyzgsHGlVWyaAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x114caacf8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy.cluster import hierarchy\n",
    "# makes dendrogram black (1)\n",
    "hierarchy.set_link_color_palette(['black'])\n",
    "\n",
    "# plot row dendrogram\n",
    "fig = plt.figure(figsize=(8,8))\n",
    "axd = fig.add_axes([0.09,0.1,0.2,0.6])\n",
    "row_dendr = dendrogram(row_clusters, orientation='left', \n",
    "                   labels=labels,\n",
    "                   color_threshold=np.inf, ) # makes dendrogram black (2))\n",
    "axd.set_xticks([])\n",
    "\n",
    "# uncomment to hide dendrogram labels\n",
    "#axd.set_yticks([])\n",
    "\n",
    "# remove axes spines from dendrogram\n",
    "for i in axd.spines.values():\n",
    "        i.set_visible(False)\n",
    "\n",
    "# reorder columns and rows with respect to the clustering\n",
    "df_rowclust = df.ix[row_dendr['leaves'][::-1]]\n",
    "        \n",
    "# plot heatmap\n",
    "axm = fig.add_axes([0.20,0.1,0.6,0.6]) # x-pos, y-pos, width, height\n",
    "cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r')\n",
    "fig.colorbar(cax)\n",
    "axm.set_xticklabels([''] + list(df_rowclust.columns))\n",
    "axm.set_yticklabels([])\n",
    "\n",
    "tick_spacing = 1\n",
    "axm.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "axm.yaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))\n",
    "\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
